<!-- 计算器的显示屏幕 -->
<template>
    <div>
        <div class="formula" ref="formula">{{ formulaStr }}</div>
        <div class="res">{{ res }}</div>
    </div>
</template>
<script setup>
import { ref, computed,nextTick,onMounted } from "vue";
const props = defineProps({
    modelValue: {
        type: String,
        required: true
    }
})
const emit = defineEmits(['update:modelValue'])
/** 正则解释 
 * 匹配位置，
 * 前面为^ 或者 空格开始的一堆数字，比如3 + 1000， 小数点后的不匹配
 * 后边为单词边界开始的 3的倍数个数字
 * [\^ ] 不行，^转不了义 
 *  */
const regExp = /(?<=(^| )\d+)(?=(\d{3})+\b)/g; /* 匹配千位分隔 , 的位置,注意小数点 .也算单词边界 */

const formulaStr = computed({
    get: () => {
        let res = props.modelValue.replace(regExp, ', ') /* 替换为千位分隔符表示 */
        //res = res.replace(/([\+\-\*\/])/g, " $1 ") /* 两边添加空格 */
        return res;
    },
    set: val => { emit("update:modelValue", val) }
})

const commandsMap = new Map([["÷", "/"], ["x", "*"], ["－", "-"], ["＋", "+"]])

const res = ref('');

function cal (str) {
    /* 计算前的 处理 */
    let newStr = str.replace(/(?<![\d\.])0+(?=[1-9]|0\.)/g, '') /* 将前置0去掉 */
    newStr = newStr.replace(/(?<![\d\.])0+$/g, '0') /* 形如 3 + 00(删除来的) 变成3 + 0*/
    newStr = newStr.replace(/(\d+)%/g, "$1/100")
    if (!/[÷x－＋](?=( \d))/g.test(newStr)) { res.value = ''; return; } /* 没有一个命令说明不用计算 结果置空 */
    commandsMap.forEach((v, k) => { /* 变成真正能计算的 + - * / */
        newStr = newStr.replaceAll(k, v)
    })

    console.log("计算：", newStr)
    try {
        res.value = eval(newStr)
        if (typeof res.value == 'number')
            res.value = res.value.toString().replace(regExp, ", ")
    } catch (error) {
        console.log(error);
        res.value = "表达式错误";
    }
}
const formula = ref(null); /* 模板引用   */
onMounted(() => {
    formula.value.addEventListener("animationend",e=>{
        e.target.classList.remove('elevate')
    })
});
function equal () {
    formulaStr.value = res.value
    res.value = ''
  formula.value.classList.add('elevate')
}
function emptyRes () {
    res.value = ''
}
defineExpose({ cal, equal, emptyRes });/* 暴露给父级调用 父组件更好掌握调用cal的时机*/


</script>
<style lang="scss" scoped>
.res {
    color: $result;
}
.formula.elevate {
    /* 让 furmula 从result的位置开始上升 */
    animation: elevate 0.5s ease-out forwards;
}
@keyframes elevate {
    from {
        transform: translateY(2.4em);
        color: $result;
    }
    to {
        transform: translateY(0);
        color: $text1;
    }
    
}
</style>